package com.itheima.proxydemo;

import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;
import org.junit.jupiter.api.Test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyDemo1 {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        //jdk动态代理
        jdkProxy();

        System.out.println("===========================");
        //只有一个接口时代理
        onlyInterfaceProxy();
    }

    /**
     * 基于jdk环境的动态代理
     */
    public static void jdkProxy() {
        //1.定义目标对象
        UserDao userDao = new UserDaoImpl();
        //2.生成代理对象 代理对象与目标对象的关系：兄弟关系
        UserDao proxyCar = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
                userDao.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * @param proxy 代理对象，开发慎用[method.invoke(proxy,args)死循环]
                     * @param method 当前调用的方法对象
                     * @param args  方法的入参
                     * @return
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //获取方法名称
                        String methodName = method.getName();
                        System.out.println(methodName + "执行了");
                        if (methodName.equals("run")) {
                            System.out.println("检查刹车是否正常。。。。。");
                        }
                        Object result = method.invoke(userDao, args);
                        //Object result = method.invoke(tesla, args);
                        System.out.println(methodName + "执行完毕");
                        return result;
                    }
                });
        //执行代理对象方法
        proxyCar.add();
    }

    /**
     * 基于接口的jdk动态代理
     * @throws InstantiationException
     * @throws IllegalAccessException
     */

    public static void onlyInterfaceProxy() throws InstantiationException, IllegalAccessException {
        Class<UserDao> userDaoClass = UserDao.class;


        UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(
                //获得类加载器
                UserDao.class.getClassLoader(),
                //将接口放入大class数组中
                new Class[]{UserDao.class},
                //拦截器,拦截方法进行增强
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("方法执行前增强....");
                        if (method.getName().equals("add")) {
                            System.out.println("add 执行了....");
                        }
                        System.out.println("方法执行增强后....");
                        return null;
                    }
                }
        );

        //执行代理后的方法
        userDaoProxy.add();
    }
}

